import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Options {

	/**
	 * The default set of variable break characters.
	 */
	private static final String DEFAULT_BREAK_CHARS = " :/.,+*()~&%$#!`\"{}|^[]\\@?<>=;";
	private static final String NONE = "";
	private File input_file_[];
	private String break_characters_;
	private CharacterAnalyzer character_analyzer_;
	private WordAnalyzer word_analyzer_;
		
	/**
	 * Constructs an instance of Options which contains all the necessary information passed by the arguments
	 * 
	 * @param input_file String containing the name of the input file.  Is "" is there is no input file (read from stdin)
	 * @param stop_file String containing the name of the stopwords file.  Is "" is there is no stopwords file
	 * @param break_characters String containing the break characters.
	 * @param thres_hold Threshold integer
	 * @param phrase_length Phrase Length int
	 * 
	 * @throws FileNotFoundException
	 * @throws IOException
	 * 
	 */
public Options(String[] input_file, String stop_file, String break_characters) throws FileNotFoundException, IOException{
		
		
		break_characters_ = break_characters;
		character_analyzer_ = new CharacterAnalyzer(break_characters);
		
		input_file_ = new File[input_file.length];
		
		for(int i = 0; i < input_file.length; i++){
			if(!input_file[i].equals(NONE))
				input_file_[i] = new File(input_file[i]);
			else
				input_file_[i] = null;
		}
			
		if(!stop_file.equals(NONE)){
			word_analyzer_ = new WordAnalyzer(new File(stop_file));
		}
		else{
			word_analyzer_ = null;
		}
	}

	public String getBreaks(){
		return break_characters_;
	}
	
	/**
	 * Static method that returns a new instance of Options with data members determined by the arguments passed from the command line
	 * 
	 * @param in_args String[] containing the arguments passed from the command line
	 * 
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws IllegalArgumentException
	 * 
	 */
	public static Options parseArguments(String[] args) throws FileNotFoundException, IOException, IllegalArgumentException{
		
		//ALL DEFAULT VALUES FOR THESE
		String break_chars = DEFAULT_BREAK_CHARS;
		String stop_file = NONE;
		String[] input_file = null;
		
		boolean isBreakSet = false;
		boolean isStopSet = false;
		boolean inputFileReached = false;
		int file_count = 0;
		

		int num_args = args.length;
		
		//Starting index is 1 since args[0] is the name of the program itself, which we don't care about
		int cur_arg_index = 0;
		
		//The program can take a maximum of 10 arguments (The first of which is the
		//program name (i.e. in_args[0] = "Histo")
		
		if(num_args == 0){
			throw new IllegalArgumentException("too few arguments");
		}
		
		for(; cur_arg_index < num_args; cur_arg_index += 2){
			switch(getOptionArg(args[cur_arg_index])){
			
				case 0:
					
					if(!inputFileReached){
						file_count = args.length - cur_arg_index;
						input_file = new String[file_count];
						inputFileReached = true;
					}
					
					for(int i = 0; i < file_count; i++){
						input_file[i] = args[cur_arg_index];
						cur_arg_index++;
					}

					break;
					
				case 'b':
					if(!isBreakSet){
						break_chars = args[cur_arg_index + 1];	
						isBreakSet = true;
					}
					else
						throw new IllegalArgumentException("option -b listed more than once");
					break;
					
				case 's':
					if(!isStopSet){
						stop_file = args[cur_arg_index + 1];
						isStopSet = true;
					}
					else
						throw new IllegalArgumentException("option -s listed more than once");
					break;
					
				default:
					throw new IllegalArgumentException("option -" + getOptionArg(args[cur_arg_index]) +" not recognized");
				}
		}
				
		return new Options(input_file, stop_file, break_chars);
	}
	
	/**
	 * This method determines if a String argument is an option declaration.  Returns the
	 * single character that defines that option (i.e. returns 'b' if String is "-b").
	 * Returns 0 if the parameter String is not an option declaration.
	 * 
	 * @param arg A String comprising a single argument from the command line.
	 * 
	 * @return The option character following the '-' from the command line.  Returns 0
	 * 			if the String is not a 2 letter string with the following two rules:
	 * 			1) First character is '-'
	 * 			2) Second character is any ASCII character able to be typed from the keyboard.
	 */
	
	public static char getOptionArg(String arg){
		if(arg.length() == 2)
			if(arg.charAt(0) == '-')
				return arg.charAt(1);
		return 0;
	}
	
	public File[] getInputFile(){
		return input_file_;
	}
	
	public CharacterAnalyzer getCharacterAnalyzer(){
		return character_analyzer_;
	}
	
	public WordAnalyzer getWordAnalyzer(){
		return word_analyzer_;
	}
}
